﻿# -*- coding:utf-8 -*-
#! python3

from facecat import *
import pyctp
import os
import timer

#更新悬浮状态
#views:视图集合
def updateView(views):
	updateViewDefault(views)

#绘制视图
#view:视图
#paint:绘图对象
#drawRect:区域
def onPaint(view, paint, clipRect):
	onPaintDefault(view, paint, clipRect)

#绘制视图边线
#view:视图
#paint:绘图对象
#drawRect:区域
def onPaintBorder(view, paint, clipRect):
	onPaintBorderDefault(view, paint, clipRect)

#视图的鼠标移动方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseMove(view, mp, buttons, clicks, delta):
	onMouseMoveDefault(view, mp, buttons, clicks, delta)
		
#视图的鼠标按下方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseDown(view, mp, buttons, clicks, delta):
	onMouseDownDefault(view, mp, buttons, clicks, delta)

#视图的鼠标进入方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseEnter(view, mp, buttons, clicks, delta):
	firstTouch = False
	secondTouch = False
	firstPoint = mp
	secondPoint = mp
	if (buttons == 1):
		firstTouch = True

#视图的鼠标进入方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseLeave(view, mp, buttons, clicks, delta):
	firstTouch = False
	secondTouch = False
	firstPoint = mp
	secondPoint = mp
	if buttons == 1:
		firstTouch = True
	if view.viewType == "button":
		invalidateView(view)

#视图的鼠标抬起方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseUp(view, mp, buttons, clicks, delta):
	onMouseUpDefault(view, mp, buttons, clicks, delta)

#视图的鼠标点击方法
#view 视图
#firstTouch:是否第一次触摸 
#firstPoint:第一次触摸的坐标 
#secondTouch:是否第二次触摸 
#secondPoint:第二次触摸的坐标
#clicks 点击次数
def onClick(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks):
	onClickDefault(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks)
	global appPaint
	global ctp
	if view.viewName == "btnOrder":
		#代码输入框
		txtIssueCode = findViewByName("txtIssueCode", appPaint.views)
		#量输入框
		spinVolume = findViewByName("spinVolume", appPaint.views)
		#价格输入框
		spinPrice = findViewByName("spinPrice", appPaint.views)
		#买入单选按钮
		rbBuy = findViewByName("rbBuy", appPaint.views)
		#卖出单选按钮
		rbSell = findViewByName("rbSell", appPaint.views)
		#开仓按钮
		rbOpen = findViewByName("rbOpen", appPaint.views)
		#平今按钮
		rbCloseToday = findViewByName("rbCloseToday", appPaint.views)
		#平仓按钮
		rbClose = findViewByName("rbClose", appPaint.views)
		issueCode = getViewAttribute(txtIssueCode, "text")
		#判断输入代码是否在码表中
		if issueCode in allCodes:
			#交易所ID
			exchangeID = allCodes[issueCode].exchangeID
			#量
			volume = int(getViewAttribute(spinVolume, "text"))
			#价格
			price = float(getViewAttribute(spinPrice, "text"))
			#买
			if rbBuy.checked:
				#开仓
				if rbOpen.checked:
					ctp.bidOpen(ctp.generateReqID(), issueCode, exchangeID, price, volume, 51, "")
				#平今
				elif rbCloseToday.checked:
					ctp.bidCloseToday(ctp.generateReqID(), issueCode, exchangeID, price, volume, 51, "")
				#平仓
				elif rbClose.checked:
					ctp.bidClose(ctp.generateReqID(), issueCode, exchangeID, price, volume, 51, "")
			#卖
			else:
				#开仓
				if rbOpen.checked:
					ctp.askOpen(ctp.generateReqID(), issueCode, exchangeID, price, volume, 51, "")
				#平今
				elif rbCloseToday.checked:
					ctp.askCloseToday(ctp.generateReqID(), issueCode, exchangeID, price, volume, 51, "")
				#平仓
				elif rbClose.checked:
					ctp.askClose(ctp.generateReqID(), issueCode, exchangeID, price, volume, 51, "")
	#撤单
	elif view.viewName == "btnCancelOrder2":
		#获取委托表格
		gridOrder = findViewByName("gridOrder", appPaint.views)
		#循环遍历所有的行
		for i in range(0, len(gridOrder.rows)):
			row = gridOrder.rows[i]
			if row.selected:
				orderSysID = row.cells[0].value
				exchangeID = row.cells[16].value
				#调用撤单接口
				ctp.cancelOrder(ctp.generateReqID(), exchangeID, orderSysID, "")
				break		
	#显示持仓
	if view.viewName == "cbInvestorPosition":
		gridInvestorPosition = findViewByName("gridInvestorPosition", appPaint.views)
		gridInvestorPositionDetail = findViewByName("gridInvestorPositionDetail", appPaint.views) 
		gridInvestorPosition.visible = True
		gridInvestorPositionDetail.visible = False
		invalidateView(gridInvestorPosition)
	#显示持仓明细
	elif view.viewName == "cbInvestorPositionDetail":
		gridInvestorPosition = findViewByName("gridInvestorPosition", appPaint.views)
		gridInvestorPositionDetail = findViewByName("gridInvestorPositionDetail", appPaint.views) 
		gridInvestorPosition.visible = False
		gridInvestorPositionDetail.visible = True
		invalidateView(gridInvestorPositionDetail)
		

#视图的鼠标滚动方法
#view 视图
#mp 坐标
#buttons 按钮 0未按下 1左键 2右键
#clicks 点击次数
#delta 滚轮值
def onMouseWheel(view, mp, buttons, clicks, delta):
	onMouseWheelDefault(view, mp, buttons, clicks, delta)

#显示界面的XML
current_file_path = os.path.abspath(__file__)
current_file_dir = os.path.dirname(current_file_path)
file0 = open(current_file_dir + "\\mainframe.xml", encoding="UTF-8")
xml = file0.read()
file0.close()

#数值转字符串，可以设置保留位数
#value 数值
#digit 小数位数
def toFixed2(value, digit):
	return str(round(float(value), digit))

#创建单元格
#grid 表格
def createGridCell(grid):
	gridCell = FCGridCell()
	if grid.paint.defaultUIStyle == "dark":
		gridCell.backColor = "none"
		gridCell.borderColor = "none"
		gridCell.textColor = "rgb(255,255,255)"
	elif grid.paint.defaultUIStyle == "light":
		gridCell.backColor = "none"
		gridCell.borderColor = "none"
		gridCell.textColor = "rgb(0,0,0)"
	gridCell.font = "Default,14"
	return gridCell

#资金账户回调
def onAccountDataCallBack(data, ctpID):
	global appPaint
	#找到表格
	gridTradeAccount = findViewByName("gridTradeAccount", appPaint.views)
	gridTradeAccount.headerHeight = 30
	gridTradeAccount.showHScrollBar = True
	#改变列头的宽度
	for i in range(0,len(gridTradeAccount.columns)):
		gridTradeAccount.columns[i].allowSort = False
		gridTradeAccount.columns[i].width = 140
	#创建行
	if len(gridTradeAccount.rows) == 0:
		row = FCGridRow()
		gridTradeAccount.rows.append(row)
		for i in range(0,len(gridTradeAccount.columns)):
			cell1 = createGridCell(gridTradeAccount)
			row.cells.append(cell1)
	#填充数值
	gridTradeAccount.rows[0].cells[0].value = toFixed2(data.balance, 0)
	gridTradeAccount.rows[0].cells[1].value = toFixed2(data.closeProfit, 0)
	setCellStyle2(gridTradeAccount.rows[0].cells[1], data.closeProfit, 0)
	gridTradeAccount.rows[0].cells[2].value = toFixed2(data.floatProfit, 0)
	setCellStyle2(gridTradeAccount.rows[0].cells[2], data.floatProfit, 0)
	gridTradeAccount.rows[0].cells[3].value = toFixed2(data.positionProfit, 0)
	setCellStyle2(gridTradeAccount.rows[0].cells[3], data.positionProfit, 0)
	gridTradeAccount.rows[0].cells[4].value = toFixed2(data.dynamicBalance, 0)
	gridTradeAccount.rows[0].cells[5].value = toFixed2(data.currMargin, 0)
	gridTradeAccount.rows[0].cells[6].value = toFixed2(data.frozenCash, 0)
	gridTradeAccount.rows[0].cells[7].value = toFixed2(data.available, 0)
	gridTradeAccount.rows[0].cells[8].value = toFixed2(data.risk * 100, 2) + "%"
	gridTradeAccount.rows[0].cells[9].value = toFixed2(data.frozenMargin, 0)
	gridTradeAccount.rows[0].cells[10].value = toFixed2(data.frozenCommission, 0)
	gridTradeAccount.rows[0].cells[11].value = toFixed2(data.commission, 0)
	gridTradeAccount.rows[0].cells[12].value = toFixed2(data.preBalance, 0)
	gridTradeAccount.rows[0].cells[13].value = toFixed2(data.preCredit, 0)
	gridTradeAccount.rows[0].cells[14].value = toFixed2(data.preMortgage, 0)
	gridTradeAccount.rows[0].cells[15].value = toFixed2(data.mortgage, 0)
	gridTradeAccount.rows[0].cells[16].value = toFixed2(data.withdraw, 0)
	gridTradeAccount.rows[0].cells[17].value = toFixed2(data.deposit, 0)
	gridTradeAccount.rows[0].cells[18].value = toFixed2(data.credit, 0)
	gridTradeAccount.rows[0].cells[19].value = toFixed2(data.reserveBalance, 0)
	gridTradeAccount.rows[0].cells[20].value = toFixed2(data.withdrawQuota, 0)
	#刷新界面
	invalidateView(gridTradeAccount)

#持仓回调
def onInvestorPositionCallBack(data, ctpID):
	global appPaint
	#找到表格
	gridInvestorPosition = findViewByName("gridInvestorPosition", appPaint.views)
	#循环遍历数据
	for i in range(0, len(data)):
		#看看有没有已经存在的数据
		row = None
		for j in range(0, len(gridInvestorPosition.rows)):
			if gridInvestorPosition.rows[j].cells[0].value + gridInvestorPosition.rows[j].cells[1].value == data[i].code + data[i].posiDirection:
				row = gridInvestorPosition.rows[j]
				break
		#如果不存在就新建一行
		if row == None:
			row = FCGridRow()
			gridInvestorPosition.rows.append(row)
			for j in range(0,len(gridInvestorPosition.columns)):
				cell1 = createGridCell(gridInvestorPosition)
				row.cells.append(cell1)
		#填充数据
		row.cells[0].value = data[i].code
		row.cells[1].value = data[i].posiDirection
		row.cells[2].value = data[i].ydPosition + data[i].todayPosition
		row.cells[3].value = data[i].ydPosition
		row.cells[4].value = data[i].todayPosition
		row.cells[5].value = data[i].position - pyctp.getFrozenAmount(data[i])
		row.cells[6].value = toFixed2(data[i].positionCost, 0)
		row.cells[7].value = toFixed2(data[i].positionProfit, 0)
		setCellStyle2(row.cells[7], data[i].positionProfit, 0)
		row.cells[8].value = toFixed2(data[i].margin, 0)
		row.cells[9].value = data[i].hedgeFlag
		if data[i].code in allCodes:
			row.cells[10].value = allCodes[data[i].code].exchangeID
		else:
			row.cells[10].value = ""
		row.cells[11].value = 0
		row.cells[12].value = 0
		row.cells[13].value = 0
		row.cells[14].value = 0
		row.cells[15].value = 0
		row.cells[16].value = 0
		row.cells[17].value = 0
		row.cells[18].value = 0
		row.cells[19].value = 0
		row.cells[20].value = 0
		row.cells[21].value = 0
		row.cells[22].value = 0
		row.cells[23].value = 0
		row.cells[24].value = 0
		row.cells[25].value = toFixed2(data[i].floatProfit, 0)
		setCellStyle2(row.cells[25], data[i].floatProfit, 0)
		row.cells[26].value = 0
		row.cells[27].value = 0
		row.cells[28].value = 0
		row.cells[29].value = 0
		row.cells[30].value = 0
	#清除掉持仓量为0的行
	while 1==1:
		hasValue = False
		rowsSize = len(gridInvestorPosition.rows)
		for i in range(0, rowsSize):
			if gridInvestorPosition.rows[i].cells[2].value == 0:
				gridInvestorPosition.rows.pop(i)
				hasValue = True
				break
		if hasValue == False:
			break
	#刷新界面
	invalidateView(gridInvestorPosition)

#持仓明细回调
def onInvestorPositionDetailCallBack(data, ctpID):
	global appPaint
	#找到表格
	gridInvestorPositionDetail = findViewByName("gridInvestorPositionDetail", appPaint.views)
	#循环遍历数据
	for i in range(0, len(data)):
		#看看有没有已经存在的数据
		row = None
		for j in range(0, len(gridInvestorPositionDetail.rows)):
			if gridInvestorPositionDetail.rows[j].cells[0].value == data[i].tradeID:
				row = gridInvestorPositionDetail.rows[j]
				break
		#如果不存在就新建一行
		if row == None:  
			row = FCGridRow()
			gridInvestorPositionDetail.rows.append(row)
			for j in range(0,len(gridInvestorPositionDetail.columns)):
				cell1 = createGridCell(gridInvestorPositionDetail)
				row.cells.append(cell1)
		#填充数据
		row.cells[0].value = data[i].tradeID
		row.cells[1].value = data[i].code
		row.cells[2].value = data[i].direction
		row.cells[3].value = data[i].volume
		row.cells[4].value = toFixed2(data[i].openPrice, 0)
		row.cells[5].value = toFixed2(data[i].margin, 0)
		row.cells[6].value = data[i].tradeType
		row.cells[7].value = data[i].hedgeFlag
		row.cells[8].value = data[i].openDate
		row.cells[9].value = toFixed2(data[i].positionProfit, 0)
		row.cells[10].value = toFixed2(data[i].closeProfitByTrade, 0)
		row.cells[11].value =  data[i].exchangeID
		row.cells[12].value = "普通持仓"
		row.cells[13].value = toFixed2(data[i].preSettlementPrice, 0)
		row.cells[14].value = toFixed2(data[i].closeVolume, 0)
		row.cells[15].value = toFixed2(data[i].floatProfit, 0)
		row.cells[16].value = toFixed2(data[i].openPrice, 0)
		row.cells[17].value = data[i].combInstrumentID
	#清除掉持仓量为0的行
	while 1==1:
		hasValue = False
		rowsSize = len(gridInvestorPositionDetail.rows)
		for i in range(0, rowsSize):
			if gridInvestorPositionDetail.rows[i].cells[3].value == 0:
				gridInvestorPositionDetail.rows.pop(i)
				hasValue = True
				break
		if hasValue == False:
			break
	#刷新界面
	invalidateView(gridInvestorPositionDetail)

#委托回报回调
def onOrderInfoCallBack(data, ctpID):
	#过滤数据
	if data.orderStatus == "未知":
		return
	if len(data.orderSysID) == 0:
		return
	global appPaint
	#找到表格
	gridOrder = findViewByName("gridOrder", appPaint.views)
	#看看有没有已经存在的数据
	row = None
	for j in range(0, len(gridOrder.rows)):
		if gridOrder.rows[j].cells[0].value == data.orderSysID:
			row = gridOrder.rows[j]
			break
	#如果不存在就新建一行
	if row == None:
		row = FCGridRow()
		gridOrder.rows.insert(0, row)
		for j in range(0,len(gridOrder.columns)):
			cell1 = createGridCell(gridOrder)
			row.cells.append(cell1)
	#填充数据
	row.cells[0].value = data.orderSysID
	row.cells[1].value = data.code
	row.cells[2].value = data.direction
	row.cells[3].value = data.combOffsetFlag
	row.cells[4].value = data.orderStatus
	row.cells[5].value = toFixed2(data.limitPrice, 0)
	row.cells[6].value = data.volumeTotalOriginal
	row.cells[7].value = data.volumeTotal
	row.cells[8].value = data.volumeTotal
	row.cells[9].value = data.volumeTraded
	row.cells[10].value = data.insertTime
	row.cells[11].value = data.updateTime
	row.cells[12].value = toFixed2(data.limitPrice, 0)
	row.cells[13].value = "0"
	row.cells[14].value = "0"
	row.cells[15].value = data.combHedgeFlag
	row.cells[16].value = data.exchangeID
	row.cells[17].value = data.orderPriceType
	row.cells[18].value = data.timeCondition
	row.cells[19].value = data.orderType
	row.cells[20].value = data.userForceClose
	row.cells[21].value = data.forceCloseReason
	row.cells[22].value = ""
	row.cells[23].value = ""
	#刷新界面
	invalidateView(gridOrder)

#委托回报历史回调
def onOrderInfosCallBack(data, ctpID):
	global appPaint
	#找到表格
	gridOrder = findViewByName("gridOrder", appPaint.views)
	#清除掉所有的行
	gridOrder.rows = []
	#循环遍历所有的数据
	for i in range(0, len(data)):
		#过滤数据
		if data[i].orderStatus == "未知":
			continue
		if len(data[i].orderSysID) == 0:
			return
		#看看有没有已经存在的数据
		row = None
		for j in range(0, len(gridOrder.rows)):
			if gridOrder.rows[j].cells[0].value == data[i].orderSysID:
				row = gridOrder.rows[j]
				break
		#如果不存在就新建一行
		if(row == None):
			row = FCGridRow()
			gridOrder.rows.insert(0, row)
			for j in range(0,len(gridOrder.columns)):
				cell1 = createGridCell(gridOrder)
				row.cells.append(cell1)
		#填充数据
		row.cells[0].value = data[i].orderSysID
		row.cells[1].value = data[i].code
		row.cells[2].value = data[i].direction
		row.cells[3].value = data[i].combOffsetFlag
		row.cells[4].value = data[i].orderStatus
		row.cells[5].value = toFixed2(data[i].limitPrice, 0)
		row.cells[6].value = data[i].volumeTotalOriginal
		row.cells[7].value = data[i].volumeTotal
		row.cells[8].value = data[i].volumeTotal
		row.cells[9].value = data[i].volumeTraded
		row.cells[10].value = data[i].insertTime
		row.cells[11].value = data[i].updateTime
		row.cells[12].value = toFixed2(data[i].limitPrice, 0)
		row.cells[13].value = "0"
		row.cells[14].value = "0"
		row.cells[15].value = data[i].combHedgeFlag
		row.cells[16].value = data[i].exchangeID
		row.cells[17].value = data[i].orderPriceType
		row.cells[18].value = data[i].timeCondition
		row.cells[19].value = data[i].orderType
		row.cells[20].value = data[i].userForceClose
		row.cells[21].value = data[i].forceCloseReason
		row.cells[22].value = ""
		row.cells[23].value = ""
	#刷新界面
	invalidateView(gridOrder)

#所有收到的代码数据
allCodes = dict()
#所有收到的行情数据
allDatas = dict()
#码表回调
def onSecurityCallBack(data, ctpID):
	global appPaint
	#找到表格
	contractGrid = findViewByName("gridContracts", appPaint.views)
	#清除行
	contractGrid.rows = []
	#循环遍历所有的行
	for i in range(0, len(data)):
		#保存数据
		allCodes[data[i].instrumentID] = data[i]
		#填充数据
		row = FCGridRow()
		contractGrid.rows.append(row)
		cell1 = createGridCell(contractGrid)
		cell1.value = data[i].productID
		row.cells.append(cell1)
		cell2 = createGridCell(contractGrid)
		cell2.value = data[i].instrumentID
		row.cells.append(cell2)
		cell3 = createGridCell(contractGrid)
		cell3.value = data[i].instrumentName
		row.cells.append(cell3)
		cell4 = createGridCell(contractGrid)
		cell4.value = data[i].exchangeID
		row.cells.append(cell4)
		cell5 = createGridCell(contractGrid)
		cell5.value = data[i].volumeMultiple
		row.cells.append(cell5)
		cell6 = createGridCell(contractGrid)
		cell6.value = data[i].priceTick
		row.cells.append(cell6)
		cell7 = createGridCell(contractGrid)
		cell7.value = "期货"
		row.cells.append(cell7)
		cell8 = createGridCell(contractGrid)
		cell8.value = data[i].expireDate
		row.cells.append(cell8)
		cell9 = createGridCell(contractGrid)
		cell9.value = data[i].longMarginRatio
		row.cells.append(cell9)
		cell10 = createGridCell(contractGrid)
		cell10.value = data[i].shortMarginRatio
		row.cells.append(cell10)
		cell11 = createGridCell(contractGrid)
		cell11.value = 0
		row.cells.append(cell11)
		cell12 = createGridCell(contractGrid)
		cell12.value = 0
		row.cells.append(cell12)
		cell13 = createGridCell(contractGrid)
		cell13.value = 0
		row.cells.append(cell13)
		cell14 = createGridCell(contractGrid)
		cell14.value = 0
		row.cells.append(cell14)
		cell15 = createGridCell(contractGrid)
		cell15.value = 0
		row.cells.append(cell15)
		cell16 = createGridCell(contractGrid)
		cell16.value = 0
		row.cells.append(cell16)
		cell17 = createGridCell(contractGrid)
		cell17.value = data[i].maxMarketOrderVolume
		row.cells.append(cell17)
		cell18 = createGridCell(contractGrid)
		cell18.value = data[i].maxLimitOrderVolume
		row.cells.append(cell18)
	#刷新界面
	invalidateView(contractGrid)

#设置单元格的样式
def setCellStyle2(cell, value1, value2):
	if value1 == None or value2 == None:
		return
	if float(value1) > float(value2):
		cell.textColor = "rgb(255,0,0)"
	elif float(value1) < float(value2):
		cell.textColor = "rgb(0,255,0)"
	else:
		cell.textColor = "rgb(255,255,255)"

#当前的代码
currentCode = ""

#最新数据回调
def onSecurityLatestDataCallBack(data, ctpID):
	global appPaint	
	#找到表格
	gridLatestData = findViewByName("gridLatestData", appPaint.views)
	#找到K线
	chart = findViewByName("chart", appPaint.views)
	#循环遍历数据
	for d in range(0, len(data)):
		#看看有没有已经存在的数据
		row = None
		for i in range(0, len(gridLatestData.rows)):
			if gridLatestData.rows[i].cells[0].value == data[d].code:
				row = gridLatestData.rows[i]
				break
		#如果不存在就新建一行
		if row == None:
			row = FCGridRow()
			gridLatestData.rows.append(row)
			for j in range(0,len(gridLatestData.columns)):
				cell1 = createGridCell(gridLatestData)
				row.cells.append(cell1)
		#填充数据
		row.cells[0].value = data[d].code
		newVol = 0
		if data[d].code in allDatas:
			newVol = data[d].volume - allDatas[data[d].code].volume
		allDatas[data[d].code] = data[d]
		digit = 0
		if data[d].code in allCodes:
			row.cells[1].value = allCodes[data[d].code].instrumentName
			digit = allCodes[data[d].code].digit
		setCellStyle2(row.cells[2], row.cells[2].value, data[d].close)
		row.cells[2].value = toFixed2(data[d].close, digit)
		diff = data[d].close - data[d].preSettlementPrice
		setCellStyle2(row.cells[3], diff, 0)
		row.cells[3].value = toFixed2(diff, digit)
		setCellStyle2(row.cells[4], row.cells[4].value, data[d].bidPrice1)
		row.cells[4].value = toFixed2(data[d].bidPrice1, digit)
		row.cells[5].value = data[d].bidVolume1
		setCellStyle2(row.cells[6], row.cells[6].value, data[d].askPrice1)
		row.cells[6].value = toFixed2(data[d].askPrice1, digit)
		row.cells[7].value = data[d].askVolume1
		row.cells[8].value = data[d].volume
		row.cells[9].value = toFixed2(data[d].openInterest, digit)
		row.cells[10].value = toFixed2(data[d].upperLimit, digit)
		row.cells[11].value = toFixed2(data[d].lowerLimit, digit)
		setCellStyle2(row.cells[12], row.cells[12].value, data[d].open)
		row.cells[12].value = toFixed2(data[d].open, digit)
		row.cells[13].value = toFixed2(data[d].preSettlementPrice, digit)
		setCellStyle2(row.cells[14], row.cells[14].value, data[d].high)
		row.cells[14].value = toFixed2(data[d].high, digit)
		setCellStyle2(row.cells[15], row.cells[15].value, data[d].low)
		row.cells[15].value = toFixed2(data[d].low, digit)
		row.cells[16].value = data[d].bidVolume1
		rangeValue = 0
		if data[d].preSettlementPrice != 0:
			rangeValue = 100 * (data[d].close - data[d].preSettlementPrice) / data[d].preSettlementPrice
		row.cells[17].value = toFixed2(rangeValue, digit) + "%"
		setCellStyle2(row.cells[17], rangeValue, 0)
		row.cells[18].value = toFixed2(data[d].preClose, digit)
		row.cells[19].value = data[d].turnover
		row.cells[20].value = data[d].exchangeID
		row.cells[21].value = data[d].updateTime
		row.cells[22].value = toFixed2(data[d].preOpenInterest, digit)
		row.cells[23].value = toFixed2(data[d].close, digit)
		row.cells[24].value = toFixed2(data[d].settlementPrice, digit)
		row.cells[25].value = toFixed2(data[d].averagePrice, digit)
		row.cells[26].value = 0
		row.cells[27].value = 0
		row.cells[28].value = 0
		row.cells[29].value = 0
		row.cells[30].value = 0
		row.cells[31].value = 0
		#填充到K线
		if newVol > 0:
			if data[d].code == currentCode:
				sData = SecurityData()
				sData.date = len(chart.data) + 1
				sData.close = data[d].close
				sData.open = data[d].close
				sData.high = data[d].close
				sData.low = data[d].close
				sData.volume = newVol
				chart.data.append(sData)
				resetChartVisibleRecord(chart);
				checkChartLastVisibleIndex(chart);
				calculateChartMaxMin(chart)
				invalidateView(chart)
	#刷新界面
	invalidateView(gridLatestData)

#成交回报回调
def onTradeRecordCallBack(data, ctpID):
	#过滤数据
	if len(data.tradeID) == 0:
		return
	global appPaint
	#找到表格
	gridTradeRecord = findViewByName("gridTradeRecord", appPaint.views)
	#填充数据
	row = FCGridRow()
	gridTradeRecord.rows.insert(0, row)
	cell1 = createGridCell(gridTradeRecord)
	cell1.value = data.tradeID
	row.cells.append(cell1)
	cell2 = createGridCell(gridTradeRecord)
	cell2.value = data.code
	row.cells.append(cell2)
	cell3 = createGridCell(gridTradeRecord)
	cell3.value = data.direction
	row.cells.append(cell3)
	cell4 = createGridCell(gridTradeRecord)
	cell4.value = data.offsetFlag
	row.cells.append(cell4)
	cell5 = createGridCell(gridTradeRecord)
	cell5.value = toFixed2(data.price, 0)
	row.cells.append(cell5)
	cell6 = createGridCell(gridTradeRecord)
	cell6.value = toFixed2(data.volume, 0)
	row.cells.append(cell6)
	cell7 = createGridCell(gridTradeRecord)
	cell7.value = data.tradeTime
	row.cells.append(cell7)
	cell8 = createGridCell(gridTradeRecord)
	cell8.value = data.orderSysID
	row.cells.append(cell8)
	cell9 = createGridCell(gridTradeRecord)
	cell9.value = "普通成交"
	row.cells.append(cell9)
	cell10 = createGridCell(gridTradeRecord)
	cell10.value = data.hedgeFlag
	row.cells.append(cell10)
	cell11 = createGridCell(gridTradeRecord)
	cell11.value = data.exchangeID
	row.cells.append(cell11)
	cell12 = createGridCell(gridTradeRecord)
	cell12.value = data.commission
	row.cells.append(cell12)
	#刷新界面
	invalidateView(gridTradeRecord)

#成交回报历史回调
def onTradeRecordsCallBack(data, ctpID):
	global appPaint
	#找到表格
	gridTradeRecord = findViewByName("gridTradeRecord", appPaint.views)
	#清除所有的行
	gridTradeRecord.rows = []
	#循环遍历数据
	for i in range(0, len(data)):
		if len(data[i].tradeID) == 0:
			return
		#填充数据
		row = FCGridRow()
		gridTradeRecord.rows.insert(0, row)
		cell1 = createGridCell(gridTradeRecord)
		cell1.value = data[i].tradeID
		row.cells.append(cell1)
		cell2 = createGridCell(gridTradeRecord)
		cell2.value = data[i].code
		row.cells.append(cell2)
		cell3 = createGridCell(gridTradeRecord)
		cell3.value = data[i].direction
		row.cells.append(cell3)
		cell4 = createGridCell(gridTradeRecord)
		cell4.value = data[i].offsetFlag
		row.cells.append(cell4)
		cell5 = createGridCell(gridTradeRecord)
		cell5.value = toFixed2(data[i].price, 0)
		row.cells.append(cell5)
		cell6 = createGridCell(gridTradeRecord)
		cell6.value = toFixed2(data[i].volume, 0)
		row.cells.append(cell6)
		cell7 = createGridCell(gridTradeRecord)
		cell7.value = data[i].tradeTime
		row.cells.append(cell7)
		cell8 = createGridCell(gridTradeRecord)
		cell8.value = data[i].orderSysID
		row.cells.append(cell8)
		cell9 = createGridCell(gridTradeRecord)
		cell9.value = "普通成交"
		row.cells.append(cell9)
		cell10 = createGridCell(gridTradeRecord)
		cell10.value = data[i].hedgeFlag
		row.cells.append(cell10)
		cell11 = createGridCell(gridTradeRecord)
		cell11.value = data[i].exchangeID
		row.cells.append(cell11)
		cell12 = createGridCell(gridTradeRecord)
		cell12.value = data[i].commission
		row.cells.append(cell12)
	#刷新界面
	invalidateView(gridTradeRecord)

ctp = None #CTP对象

#检查CTP的数据
def checkCTPData(a='', b=''):
	global ctp
	#检查是否有最新的数据
	while ctp.hasNewDatas():
		recvData = create_string_buffer(102400)
		#接收最新行情
		if ctp.getDepthMarketData(recvData) > 0:
			data = pyctp.convertToCTPDepthMarketData(str(recvData.value, encoding="gbk"))
			onSecurityLatestDataCallBack(data, ctp.ctpID)
			continue
		#接收资金数据
		if ctp.getAccountData(recvData) > 0:
			data = pyctp.convertToCTPAccountData(str(recvData.value, encoding="gbk"))
			onAccountDataCallBack(data, ctp.ctpID)
			continue
		#接收委托回报
		if ctp.getOrderInfo(recvData) > 0:
			data = pyctp.convertToCTPOrder(str(recvData.value, encoding="gbk"))
			onOrderInfoCallBack(data, ctp.ctpID)
			continue
		#接收成交回报
		if ctp.getTradeRecord(recvData) > 0:
			data = pyctp.convertToCTPTrade(str(recvData.value, encoding="gbk"))
			onTradeRecordCallBack(data, ctp.ctpID)
			continue
		#接收持仓
		if ctp.getPositionData(recvData) > 0:
			data = pyctp.convertToCTPInvestorPosition(str(recvData.value, encoding="gbk"))
			onInvestorPositionCallBack(data, ctp.ctpID)
			continue
		#接收持仓明细
		if ctp.getPositionDetailData(recvData) > 0:
			data = pyctp.convertToCTPInvestorPositionDetail(str(recvData.value, encoding="gbk"))
			onInvestorPositionDetailCallBack(data, ctp.ctpID)
			continue
		break

#启动CTP
def runCTP():
	global ctp
	global appPaint
	ctp = pyctp.CTPDLL()
	ctp.init()
	#创建CTP实例
	ctp.ctpID = ctp.create()
	ctp.setMessageID(appPaint.hWnd, 2000)
	#创建请求ID
	reqID = ctp.generateReqID()
	# 启动CTP交易和行情
	#第一组 行情:180.168.146.187:10211 交易:180.168.146.187:10201
	#第二组 行情:180.168.146.187:10212 交易:180.168.146.187:10202
	#第三组 行情:218.202.237.33:10213 交易:218.202.237.33:10203
	#第四组 行情:180.168.146.187:10131 交易:180.168.146.187:10130
	ctp.start(reqID, "simnow_client_test", "0000000000000000", "218.202.237.33:10213", "218.202.237.33:10203", "9999", "021739", "123456")
	# 检查是否登陆成功
	while (ctp.isDataOk() <= 0):
		time.sleep(1)
	print("登陆CTP成功!")
	#接收码表
	recvData = create_string_buffer(1024 * 1024 * 10)
	if ctp.getInstrumentsData(recvData) > 0:
		data = pyctp.convertToCTPInstrumentDatas(str(recvData.value, encoding="gbk"))
		onSecurityCallBack(data, ctp.ctpID)
	#接收委托回报历史
	recvData = create_string_buffer(1024 * 1024 * 10)
	if ctp.getOrderInfos(recvData) > 0:
		data = pyctp.convertToCTPOrderList(str(recvData.value, encoding="gbk"))
		onOrderInfosCallBack(data, ctp.ctpID)
	#接收成交回报历史
	recvData = create_string_buffer(1024 * 1024 * 10)
	if ctp.getTradeRecords(recvData) > 0:
		data = pyctp.convertToCTPTradeRecords(str(recvData.value, encoding="gbk"))
		onTradeRecordsCallBack(data, ctp.ctpID)
	#注册行情
	ctp.subMarketDatas(reqID, "cu2403,cu2404,cu2405,rb2403,rb2404,rb2405,ru2403,ru2404,ru2405,IF2404")
	#启动秒表
	#timer.set_timer(100, checkCTPData)

#点击单元格
def onClickGridCell(grid, row, gridColumn, cell, firstTouch, firstPoint, secondTouch, secondPoint, clicks):
	global appPaint
	global currentCode
	gridName = grid.viewName
	if gridName == "gridLatestData":
		#从选中的最新行情自动填写信息到下单界面中
		chart = findViewByName("chart", appPaint.views)
		chart.data = []
		calculateChartMaxMin(chart)
		code = row.cells[0].value
		currentCode = code
		price = row.cells[2].value
		txtIssueCode = findViewByName("txtIssueCode", appPaint.views)
		spinPrice = findViewByName("spinPrice", appPaint.views)
		spinVolume = findViewByName("spinVolume", appPaint.views)
		setViewAttribute(txtIssueCode, "text", code)
		setViewAttribute(spinPrice, "text", price)
		setViewAttribute(spinVolume, "text", "1")
		invalidate(appPaint)
	elif gridName == "gridInvestorPosition":
		#从选中的持仓自动填写信息到下单界面中
		code = row.cells[0].value
		price = ""
		if code in allDatas:
			price = str(allDatas[code].close)
		txtIssueCode = findViewByName("txtIssueCode", appPaint.views)
		spinPrice = findViewByName("spinPrice", appPaint.views)
		spinVolume = findViewByName("spinVolume", appPaint.views)
		setViewAttribute(txtIssueCode, "text", code)
		setViewAttribute(spinPrice, "text", price)
		setViewAttribute(spinVolume, "text", "1")
		invalidate(appPaint)
	elif(gridName == "gridInvestorPositionDetail"):
		#从选中的持仓明细自动填写信息到下单界面中
		code = row.cells[1].value
		price = ""
		if code in allDatas:
			price = str(allDatas[code].close)
		txtIssueCode = findViewByName("txtIssueCode", appPaint.views)
		spinPrice = findViewByName("spinPrice", appPaint.views)
		spinVolume = findViewByName("spinVolume", appPaint.views)
		setViewAttribute(txtIssueCode, "text", code)
		setViewAttribute(spinPrice, "text", price)
		setViewAttribute(spinVolume, "text", "1")
		invalidate(appPaint)

appPaint = FCPaint() #创建绘图对象
appPaint.defaultUIStyle = "dark"
#注册回调事件
appPaint.onPaint = onPaint 
appPaint.onPaintBorder = onPaintBorder
appPaint.onMouseDown = onMouseDown 
appPaint.onMouseMove = onMouseMove 
appPaint.onMouseUp = onMouseUp
appPaint.onMouseWheel = onMouseWheel
appPaint.onMouseEnter = onMouseEnter
appPaint.onMouseLeave = onMouseLeave
appPaint.onClick = onClick
appPaint.onClickGridCell = onClickGridCell
appPaint.onUpdateView = updateView

#消息循环
def WndProc(hwnd,msg,wParam,lParam):
	if msg == 2000:
		checkCTPData()
		return 1
	else:
		return WndProcDefault(appPaint,hwnd,msg,wParam,lParam)	
	
#创建窗体
setMaxWindow()
createMainWindow(appPaint, "facecat-py", WndProc)
appPaint.init()
appPaint.allowPartialPaint = False
appPaint.systemFont = "SimSun"
appPaint.gdiPlusPaint.encoding = "utf-8"
renderFaceCat(appPaint, xml)
#找到K线并设置属性
chart = findViewByName("chart", appPaint.views)
chart.candleDivPercent = 0.7
chart.volDivPercent = 0.3
chart.indDivPercent = 0
chart.cycle = "trend"
chart.backColor = "rgb(0,0,0)"
chart.borderColor = "rgb(100,100,100)"
chart.textColor = "rgb(255,255,255)"
chart.scaleColor = "rgb(100,100,100)"
chart.crossTipColor = "rgb(50,50,50)"
chart.crossLineColor = "rgb(100,100,100)"
chart.gridColor = "rgba(100,100,100,125)"
chart.indicatorColors = []
chart.indicatorColors.append("rgb(255,255,255)")
chart.indicatorColors.append("rgb(255,255,0)")
chart.indicatorColors.append("rgb(255,0,255)")
chart.indicatorColors.append("rgb(255,0,0)")
chart.indicatorColors.append("rgb(0,255,255)")
chart.indicatorColors.append("rgb(0,255,0)")
chart.indicatorColors.append("rgb(255,255,0)")
chart.indicatorColors.append("rgb(255,255,255)")
#启动CTP
runCTP()
showWindow(appPaint)
